/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.googlecode.canoe.core.session.support;

import com.googlecode.canoe.core.session.Role;
import com.googlecode.canoe.core.session.Session;
import com.googlecode.canoe.core.session.SessionRoleManager;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 *
 * @author panzd
 */
public class DefaultSessionRoleManager implements SessionRoleManager {
    private ConcurrentMap<Role, Session> roleSessionMap;
    private ConcurrentMap<Integer, Role> roleMap;
    private ConcurrentMap<Long, Session> sessionMap;

    /**
     * @return the sessionMap
     */
    protected ConcurrentMap<Role, Session> getRoleSessionMap() {
        return roleSessionMap;
    }

    /**
     * @return the roleMap
     */
    protected ConcurrentMap<Integer, Role> getRoleMap() {
        return roleMap;
    }

    public DefaultSessionRoleManager() {
        roleSessionMap = new ConcurrentHashMap<Role, Session>();
        roleMap = new ConcurrentHashMap<Integer, Role>();
        sessionMap = new ConcurrentHashMap<>();
    }

    public Role getRoleById(int id) {
        return getRoleMap().get(id);
    }

    public Collection<Role> getAllRoles() {
        return getRoleSessionMap().keySet();
    }

    public void join(Role role, Session session) {
        if (role == null || session == null || role == session.getRole())
            return;

        exit(role);
        session.setRole(role);

        Session lastSession = getSession(role);
        if (session != lastSession) {
            if (lastSession != null) {
                lastSession.setRole(null);
            }

            getRoleSessionMap().put(role, session);
            getRoleMap().put(role.getId(), role);
        }
    }

    public void exit(Role user) {
        if (user == null) {
            return;
        }

        Session session = getSession(user);
        if (session != null) {
            session.setRole(null);

            getRoleSessionMap().remove(user);
            getRoleMap().remove(user.getId());
        }
    }

    public void addSession(Session session) {
        sessionMap.put(session.getId(), session);
    }

    public void removeSession(Session session) {
        sessionMap.remove(session.getId());
    }

    public Session getSession(Role user) {
        return getRoleSessionMap().get(user);
    }

    public Session getSession(long id) {
        return sessionMap.get(id);
    }

    @Override
    public Collection<Session> getAllSessions() {
        return sessionMap.values();
    }
}
